import {
  FC,
  ReactElement,
  useCallback,
  useState,
  useRef,
  useMemo,
  useEffect,
} from "react";
import styled from "styled-components";
import { Button, Form, Input, Space } from "antd";
import "antd/es/modal/style";
import {
  createNewPoker,
  Poker,
  PokerProps,
  updatePoker,
} from "../../../api/pokerAPI";
import ImageCropper from "../../ImageCropper";
import ImageList from "./ImageList";
import { FlexDiv } from "../../BUI";
import {
  NotificationSuccess,
  NotificationWarn,
} from "../../common/Notification";

export const objToArr = (obj: any) =>
  Object.entries(obj).map(item => ({ name: item[0], value: item[1] }));

interface FormConfigProps {
  title: string;
  name: string;
  rules?: Array<{ required: boolean; message: string }>;
  inputProp?: { [key: string]: any };
}

interface IProps {
  onCreateNewPoker: (Poker: Poker) => void;
  onCancelUpdatePoker: () => void;
  handleUpdatePoker: (Poker: PokerProps) => void;
  update?: boolean;
  updateData?: PokerProps;
  pokerLength: number;
}

const AddNewPoker: FC<IProps> = ({
  onCreateNewPoker,
  handleUpdatePoker,
  onCancelUpdatePoker,
  update,
  updateData,
  pokerLength,
}): ReactElement => {
  const [fileList, setFileList] = useState<any>([]);
  const [updateFileIndex, setUpdateFileIndex] = useState(-1);
  const [loading, setLoading] = useState(false);
  const form = useRef<any>(null);
  const imageCropper = useRef<any>(null);

  const setLevelFromProps = useCallback(() => {
    form.current?.setFields([{ name: "level", value: pokerLength }]);
  }, [pokerLength]);

  useEffect(() => {
    setLevelFromProps();
  }, [setLevelFromProps]);

  const FormConfig: FormConfigProps[] = useMemo(
    () => [
      {
        name: "title",
        title: "标题",
        rules: [{ required: true, message: "Please input title!" }],
      },
      {
        name: "description",
        title: "描述",
        rules: [{ required: true, message: "Please input description!" }],
      },
      {
        name: "level",
        title: "优先级",
        inputProp: {
          type: "number",
          max: 1000,
          min: 0,
        },
        rules: [{ required: true, message: "Please input level!" }],
      },
      {
        name: "url",
        title: "预览地址",
        rules: [{ type: "url", required: true, message: "Please input URL!" }],
      },
    ],
    []
  );

  const ButtonGroup: any = useMemo(
    () =>
      update
        ? [
            { type: "primary", htmlType: "submit", loading, children: "更新" },
            { type: "dashed", children: "取消", onClick: onCancelUpdatePoker },
          ]
        : [
            { type: "primary", htmlType: "submit", loading, children: "提交" },
            { type: "dashed", htmlType: "reset", children: "重置" },
          ],
    [loading, onCancelUpdatePoker, update]
  );

  const resetForm = useCallback(() => {
    //重置表单
    setFileList([]);
    form.current.resetFields(["title", "description", "url"]);
    setLevelFromProps();
  }, [setLevelFromProps]);

  useEffect(() => {
    if (update && updateData) {
      const { images, ...poker } = updateData;
      console.log("render:", poker);
      setFileList(images);
      form.current.setFields(objToArr(poker));
    } else if (!update && updateData) {
      console.log("回到创建模式");
      resetForm();
    }
  }, [resetForm, update, updateData]);

  const handleSubmit = useCallback(
    async poker => {
      const { data } = await createNewPoker(poker);
      setLoading(false);
      if (!data) return;
      console.log("insert poker item:", data);

      NotificationSuccess({
        message: "添加成功",
        description: "vary Good.",
      });
      //重置表单
      resetForm();
      //将新数据传递给父级
      onCreateNewPoker(data);
    },
    [onCreateNewPoker, resetForm]
  );

  const handleUpdate = useCallback(
    async (poker: PokerProps) => {
      //@ts-ignore
      const updateItem: any = { _id: updateData._id };

      for (const [key, value] of Object.entries(poker)) {
        //@ts-ignore
        if (JSON.stringify(value) !== JSON.stringify(updateData[key])) {
          //@ts-ignore
          updateItem[key] = value;
        }
      }

      const { data } = await updatePoker(updateItem);
      setLoading(false);
      if (!data) return;
      NotificationSuccess({
        message: "更新成功",
        description: "vary Good.",
      });
      handleUpdatePoker(data);
    },
    [updateData, handleUpdatePoker]
  );

  const onFinish = useCallback(
    async (values: any) => {
      if (!fileList.length) {
        return NotificationWarn({
          message: "添加失败",
          description: "图片不能为空",
        });
      }
      setLoading(true);
      const poker: any = {
        ...values,
        images: fileList,
        level: parseInt(values.level),
      };
      console.log("poker:", poker);
      if (update) handleUpdate(poker);
      else handleSubmit(poker);
    },
    [fileList, handleSubmit, handleUpdate, update]
  );

  const onDeleteFileItem = useCallback(
    (index: number) => () => {
      setFileList((prev: any) => {
        const list = [...prev];
        list.splice(index, 1);
        return list;
      });
    },
    []
  );

  const handleCrop = useCallback(
    (file: any) => {
      console.log("file:", file);
      if (updateFileIndex === -1) {
        setFileList((prev: any) => [...prev, file]);
      } else {
        setFileList((prev: any) => {
          const list = [...prev];
          list.splice(updateFileIndex, 1, file);
          return list;
        });
        setUpdateFileIndex(-1);
      }
    },
    [updateFileIndex]
  );

  const updateImageCropper = useCallback(
    index => () => {
      setUpdateFileIndex(index);
      imageCropper.current.click();
    },
    [imageCropper]
  );

  const Title = useMemo(
    () => (update ? <h2>更新poker</h2> : <h2>添加新内容</h2>),
    [update]
  );

  const renderInput = useCallback(
    (item: FormConfigProps) => (
      <Form.Item
        key={item.name}
        label={item.title}
        name={item.name}
        rules={item.rules}
      >
        <Input {...item.inputProp} />
      </Form.Item>
    ),
    []
  );

  return (
    <Container>
      {Title}
      <Form
        ref={form}
        name='poker'
        labelCol={{ span: 4 }}
        wrapperCol={{ span: 12 }}
        onFinish={onFinish}
      >
        {FormConfig.map(renderInput)}
        <Form.Item label='展示图片(必填)'>
          <FlexDiv>
            <ImageList
              onDeleteFileItem={onDeleteFileItem}
              updateImageCropper={updateImageCropper}
              update={update}
              fileList={fileList}
              appendChildren={
                <ImageCropper ref={imageCropper} onCrop={handleCrop} />
              }
            />
            {/* <ImageCropper ref={imageCropper} onCrop={handleCrop} /> */}
          </FlexDiv>
        </Form.Item>
        <Form.Item wrapperCol={{ offset: 8, span: 16 }}>
          <Space size='large'>
            {ButtonGroup.map((button: any) => (
              <Button key={button.children} {...button} />
            ))}
          </Space>
        </Form.Item>
      </Form>
    </Container>
  );
};

export default AddNewPoker;

const Container = styled.div`
  width: 60%;
  height: 100%;
  border-right: 1px solid var(--border-color);
`;
